﻿Namespace Settings

    Public Class NumberSetting
        Inherits TextSetting

        Dim mLowerBound As Double = Double.NaN
        Dim mUpperBound As Double = Double.NaN
        Dim mAllowDecimal As Boolean = False

        Public Property LowerBound As Double
            Get
                Return mLowerBound
            End Get
            Set(ByVal value As Double)
                mLowerBound = value
            End Set
        End Property

        Public Property UpperBound As Double
            Get
                Return mUpperBound
            End Get
            Set(ByVal value As Double)
                mUpperBound = value
            End Set
        End Property

        Public Property AllowDecimal As Boolean
            Get
                Return mAllowDecimal
            End Get
            Set(ByVal value As Boolean)
                mAllowDecimal = value
            End Set
        End Property


        Public Sub New(ByVal id As SettingKey,
                      ByVal name As String,
                      ByVal desc As String,
                      ByVal val As Object)
            MyBase.New(id, name, desc, val)
        End Sub


        Protected Overrides Function getUIElement() As System.Windows.Controls.Control
            Dim tb = CType(MyBase.getUIElement, TextBox)

            ' Add additional event handler
            AddHandler tb.PreviewTextInput, AddressOf textInputHandler
            Return tb

        End Function

        Protected Overrides Function getValueFromString(ByVal value As String) As Object
            Return CDbl(value)
        End Function

        Protected Overrides Sub validateValue(ByVal value As Object)
            Dim passed As Boolean = False
            Try
                Dim numVal As Double = CDbl(value)
                Dim res As Boolean = False
                ' Test Lower Bound
                If Double.IsNaN(mLowerBound) Then
                    passed = True
                Else
                    passed = (numVal >= mLowerBound)
                End If

                ' Test UpperBound
                If passed = True Then
                    If Not Double.IsNaN(mUpperBound) Then
                        passed = (numVal <= mUpperBound)
                    End If
                End If
            Catch ex As Exception
                passed = False
            End Try

            If Not passed Then
                Throw New ArgumentOutOfRangeException(Me.Name, value, getErrorMsg())
            End If
        End Sub

        Private Sub textInputHandler(ByVal sender As Object, ByVal e As TextCompositionEventArgs)
            Dim ok As Boolean = False
            Dim charTyped As String = e.Text
            Dim curText As String = CType(sender, TextBox).Text
            If (charTyped = "+" Or charTyped = "-") And (curText = "") Then
                ok = True
            ElseIf (charTyped = "." And
                     Me.AllowDecimal And
                     Not curText.Contains(".")) Then
                ok = True
            Else

                ok = IsNumeric(charTyped)
            End If
            e.Handled = Not ok
        End Sub

        Private Function getErrorMsg() As String
            Dim msg = "Value must be a"

            If Me.AllowDecimal Then
                msg &= " Real number"
            Else
                msg &= " Whole number"
            End If

            If Double.IsNaN(mLowerBound) Then
                If Double.IsNaN(mUpperBound) Then
                    msg &= "."
                Else
                    msg &= " less than or equal to " & mUpperBound & "."
                End If
            Else
                If Double.IsNaN(mUpperBound) Then
                    msg &= " greater than or equal to " & mLowerBound & "."
                Else
                    msg &= " greater than or equal to " & mLowerBound & " and less than or equal to " & mUpperBound & "."
                End If
            End If
            Return msg
        End Function

    End Class

End Namespace
